package thread;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Duanyu
 * @date 2021-11-15 19:29
 */
public class CallableTest {


    @Test
    public void test4() {

        try {
            CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(()->{
                System.out.println(Thread.currentThread().getName() + "supplyAsync=>Integer");
                int i = 10/0;
                return 666;
            });
            // t为正常的返回结果，如果异常则在u中返回
            int integer = completableFuture2.whenComplete((t, u) -> {
                // 正常的返回结果
                System.out.println("t==>" + t);
                // java.util.concurrent.CompletionException
                System.out.println("u==>" + u);
            }).exceptionally(e -> {
                // 这里面可以对异常再次进行处理并且返回
                System.out.println(e.getMessage());
                return 111;
            }).get();

            System.out.println(integer);


        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(2);
        for (String s : Arrays.asList("A", "B", "C", "D")) {
            new Thread(() -> {
                try {
                    //抢占许可
                    semaphore.acquire();

                    System.out.println(Thread.currentThread().getName() + "吃饭");

                    TimeUnit.SECONDS.sleep(new Random().nextInt(5));

                    System.out.println(Thread.currentThread().getName() + "吃饱了,离开");

                } catch (Exception e) {
                } finally {
                    //释放许可
                    semaphore.release();
                }
            }, s).start();
        }
    }


    @Test
    public void test3() {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> System.out.println("点火~~"));
        for (String s : Arrays.asList("A", "B", "C")) {
            new Thread(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + "通过！");

                    cyclicBarrier.await();

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, s).start();
        }
    }

    static ExecutorService pool = Executors.newFixedThreadPool(6);


    @Test
    public void test1() throws ExecutionException, InterruptedException {
        FutureTask<List<Integer>> futureTask = new FutureTask<>(() -> {
            CountDownLatch countDownLatch = new CountDownLatch(3000);
            CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>();
            for (String s : Arrays.asList("A", "B", "C")) {
                new Thread(() -> {
                    for (int i = 0; i < 1000; i++) {
                        list.add(i);
                        countDownLatch.countDown();
                    }
                }, s).start();
            }
            countDownLatch.await();
            return list;
        });
        new Thread(futureTask).start();
        System.out.println(futureTask.get().size());
    }


    @Test
    public void test() {

        FutureTask<List<Integer>> futureTask = new FutureTask<>(() -> Stream.iterate(0, v -> v + 1).limit(10000).collect(Collectors.toList()));
        int i = 0;
        pool.execute(() -> {
            for (int j = 0; j < 100; j++) {

                System.out.println(j);
            }

        });

        pool.submit(futureTask);

        try {
            System.out.println(futureTask.get().size());
            System.out.println("ddddd");
            System.out.println(futureTask.get().size());
            //TimeUnit.SECONDS.sleep(5);


        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
